# koroFileHeader at Yungoal acer
# Create: 2022-10-13 17:30:58
# LastEdit: 2022-10-26 16:21:59
"""说明暂无"""
__author__ = '749B'

import json

from django.db.models import Sum
from django.db.models.functions import ExtractYear, ExtractMonth
from django.shortcuts import HttpResponse, render

from pyecharts.charts import Bar, Timeline
from pyecharts.components import Table
from pyecharts import options as opts

from utils.cache import cache_auto_key

from .. import models
from .restapi import JsonResponse

import logging
logger = logging.getLogger(__name__)
logger.success = lambda msg, *args, **kwargs: logger.log(25, msg, *args, **kwargs)  # type: ignore


# Create your views here.
def monthly(request):
    sub_list = models.Subscriptions.objects.values('id', 'name') 
    return render(
        request, 
        "billing/monthly.html", 
        {'sub_list': sub_list},
        )

def cost_monthly(request):
    subid = request.GET.get('subid')
    if subid:
        company_name = models.Account.objects.values_list('name', flat=True).first()
        name, usage_budget = models.Subscriptions.objects.values_list('name', 'usage_budget').get(id=subid)

        qs_sub = models.Detail.objects.filter(subscription_id=subid)
        # 先添加注解，提取出年和月
        qs_year_month = qs_sub.annotate(year=ExtractYear('date'), month=ExtractMonth('date'))
        # 然后按年和月分组
        qs_groupby = qs_year_month.values('year', 'month')
        # 最后再求和，然后只要最近12个月的
        qs = qs_groupby.annotate(cost=Sum('extended_cost')).order_by('-year', '-month')[:12:-1]

        bar = Bar()
        bar.add_xaxis([ f"{i['year']}-{i['month']}" for i in qs ])
        bar.add_yaxis('订阅消费金额', [ round(i['cost'], 2) for i in qs ])
        bar.set_global_opts(
            title_opts=opts.TitleOpts(title=name, subtitle=company_name),
            legend_opts=opts.LegendOpts(selected_mode=False),
            )
        bar.set_series_opts(
            label_opts=opts.LabelOpts(is_show=True),  # 柱状图上显示数字
            markline_opts=opts.MarkLineOpts(
                data=[opts.MarkLineItem(y=usage_budget)],
                label_opts=opts.LabelOpts(
                    color='red', 
                    formatter=format(int(usage_budget), ',')
                    ),
                linestyle_opts=opts.LineStyleOpts(color='red'),
                ) if usage_budget else None
            )
    else:
        company_name, enrollment = models.Account.objects.values_list('name', 'enrollment').first() or (None, None)
        rows = models.Summary.objects.order_by('-report_month')[:12:-1]

        bar = Bar()
        bar.add_xaxis([ str(row) for row in rows ])
        bar.add_yaxis('总消费金额', [ round(float(row.total_usage), 2) for row in rows ])
        bar.set_global_opts(
            title_opts=opts.TitleOpts(title=enrollment, subtitle=company_name),
            legend_opts=opts.LegendOpts(selected_mode=False),
            )
    c = bar.dump_options_with_quotes()
    return JsonResponse(json.loads(c))


def table(request):
    return render(request, "billing/table.html", )

def cost_table(request):
    company_name, enrollment = models.Account.objects.values_list('name', 'enrollment').first() or (None, None)
    sub_list = models.Subscriptions.objects.values('id', 'name') 

    qs = (
        models.report.Detail.objects
        .annotate(year=ExtractYear('date'), month=ExtractMonth('date'))
        .values('subscription', 'year', 'month')
        .annotate(cost=Sum('extended_cost'))
        .order_by('year', 'month', 'subscription')
        )
    data = {}
    for i in qs:
        month = f"{i['year']}-{i['month']:0>2d}"
        data.setdefault(month, {}) 
        data[month][i['subscription']] = i['cost']
    
    table_headers = ['subscription'] + list(data.keys())
    table_rows = []

    for sub in sub_list:
        subid = sub['id']
        subname = sub['name']
        row = [subname]
        for sub_dict in data.values():
            cost = sub_dict.get(subid)
            row.append(format(cost, '.2f') if cost is not None else 0)
        table_rows.append(row)

    table = (
        Table()
        .add(
            [table_headers[0]] + table_headers[-12:] if len(table_headers) > 12 else table_headers, 
            [ [row[0]] + row[-12:] if len(row) > 12 else row for row in table_rows ],
            )
        .set_global_opts(
            title_opts=opts.ComponentTitleOpts(title=enrollment, subtitle=company_name)
            )
        )
    return HttpResponse(table.render_embed())  


def screen(request):
    return render(request, "billing/screen.html")

@cache_auto_key(cache_key='nohash')
def cost_subscription_month_cache():
    logger.debug('调用缓存: primary.cost_subscription_month_cache')
    qs = (
        models.report.Detail.objects.annotate(year=ExtractYear('date'), month=ExtractMonth('date'))
        .values('subscription', 'year', 'month')
        .annotate(cost=Sum('extended_cost'))
        )
    return qs

def cost_screen(request):
    company_name = models.Account.objects.values_list('name', flat=True).first()
    sub_list = models.Subscriptions.objects.values('id', 'name') 
    subid_list = [ sub['id'] for sub in sub_list]
    subname_list = [ sub['name'] for sub in sub_list]
    
    # 调用缓存
    qs = cost_subscription_month_cache()

    date = {}
    for i in qs:
        key = f"{i['year']}-{i['month']:0>2d}"
        date.setdefault(key, {})            
        date[key][i['subscription']] = i['cost']

    def get_month_chart(month: str) -> Bar:
        date_m = []  
        # 要把数据按照x轴的顺序排好。可能有的月份记录不全，要在对应位置补上None
        for subid in subid_list:
            v = date[month].get(subid)
            date_m.append(v)
        bar = Bar()
        bar.add_xaxis(xaxis_data=subname_list)
        bar.add_yaxis('订阅月度费用', date_m,
            is_selected=True,
            label_opts=opts.LabelOpts(is_show=False),
            )
        bar.set_global_opts(
            title_opts=opts.TitleOpts(title=f"{month}", subtitle=company_name),
            tooltip_opts=opts.TooltipOpts(is_show=True, trigger="axis", axis_pointer_type="shadow"),
            legend_opts=opts.LegendOpts(selected_mode=False),
        )
        return bar

    timeline = Timeline(init_opts=opts.InitOpts())
    for m in date.keys():
        timeline.add(get_month_chart(m), time_point=m)
    timeline.add_schema(is_auto_play=True, play_interval=1000)
    c = timeline.dump_options_with_quotes()
    return JsonResponse(json.loads(c))
